<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="./css/style.css">
    <title>判断点是否在多边形内部</title>
</head>
<body>
    <div class="container">
        <canvas id="panel" width="700" height="700" ></canvas>
        <div class="info">
            <div class="btns">
                <button onclick="drawPoint()">绘制点</button>
                <button onclick="getPolygonPoints()">获得多边形点</button>
                <button onclick="drawPolygon()">绘制多边形</button>
                <button onclick="calc()">判断</button>
            </div>
            <p>结果：</p>
            <textarea name="" id="res" cols="30" rows="10"></textarea>
        </div>
    </div>
    <script>
        var canvas = document.getElementById('panel')
        var ctx= canvas.getContext('2d')
        var result = document.getElementById('res')
        var point = []
        var polygon = []

        function drawPoint() {
            let bounding = canvas.getBoundingClientRect()
            canvas.addEventListener('mousedown', function(e){
                if(point[0] == undefined && point[1] == undefined){
                    point = [e.clientX - bounding.left, e.clientY - bounding.top]
                    ctx.fillStyle = 'red'
                    ctx.fillRect(point[0], point[1], 5, 5)
                    ctx.save()
                } else {
                    return
                }

            })
        }

        function getPolygonPoints() {
            canvas.addEventListener('mousedown', function(e) {
                polygon.push([e.clientX, e.clientY])
                ctx.fillStyle = 'yellow'
                ctx.fillRect(e.clientX, e.clientY, 5, 5)
                ctx.save()
            })
        }
        function drawPolygon() {
            if (polygon.length <3) {
                alert('点小于三个，不能绘制多边形')
            } else {
                ctx.beginPath()
                ctx.moveTo(polygon[0][0], polygon[0][1])
                for (i = 1; i< polygon.length; i++) {
                    ctx.lineTo(polygon[i][0], polygon[i][1])
                }
                ctx.fillStyle = 'rgba(100, 40, 40, 0.5)'
                ctx.fill()
            }
        }
        // 判断点是否在多边形内部方法
        function calc() {

            var res = ifPointInPolygon(point, polygon)
            result.innerHTML = (res == true) ? '点在多边形内部':'点不在多边形内部'
            // console.log('结果:'+res)
        }
        // 主要算法
        function ifPointInPolygon(point, polygon) {
            var x = point[0]
            var y = point[1]
            var result = false
            for(i = 0, j = polygon.length - 1; i < polygon.length; j=i++){
                var xi = polygon[i][0]
                var yi = polygon[i][1]
                var xj = polygon[j][0]
                var yj = polygon[j][1]

                // var intersect = ((yi > y) != (yj > y)) && (x < (xj -xi) * (y -yi) / (yj - yi) + xi)
                yrange = (yi < yj )? [yi, yj] : [yj, yi]
                var intersect = (yrange[0] <= y && y <= yrange[1]) && (x < (xj -xi) * (y -yi) / (yj - yi) + xi)                
                if(intersect) {
                    result = !result
                }
            }
            return result
        }
        
    </script>
    
</body>
</html>